package com.sinovatech.ologger.actionlog.converters;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.sinovatech.ologger.actionlog.core.LogHelper;
import com.sinovatech.ologger.actionlog.dao.BeanUtilDao;
import com.sinovatech.ologger.actionlog.entity.OperationLog;
import com.sinovatech.ologger.core.util.GenericsUtils;
import com.sinovatech.ologger.util.StringHelper;

/**
 * 日志转换器工具类, 包括一些工具方法和默认转换器的实现
 * 
 * @author nanquan
 * 
 */
public class LogConverterHelper {

	private static final Log logger = LogFactory
			.getLog(LogConverterHelper.class);

	public static final String SEPARATED_COMMA = ",";

	private BeanUtilDao beanUtilDao;

	public LogConverterHelper() {
		LogHelper.registerLogConverter(new DateToYMDConverter(), "dateToYMD");// date转换为yyyy-MM-dd格式的字符串
		LogHelper.registerLogConverter(new CreateOrEditConverter(),
				"createOrEdit");// 新增或编辑
		LogHelper.registerLogConverter(new SaveOrUpdateConverter(),
				"saveOrUpdate");// 保存或更新
		LogHelper.registerLogConverter(new BooleanTypeConverter(),
				"booleanType");// 是否 转换器
	}

	/**
	 * 通过id集合 获取实体对象 暂时通过遍历一个一个得获取
	 * 使用该方法时, 需要为当前类注入BeanUtilDao
	 * @param ids
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> List<T> findObjectListByIds(List<Serializable> ids,
			Class<?> clazz) {
		if (beanUtilDao == null) {//没有提供beanUtilDao
			logger.error("必须为" + this.getClass().getName() + "注入beanUtilDao");
			beanUtilDao.toString();//抛出异常
		}
		List<T> list = new ArrayList<T>();
		for (Serializable id : ids) {
			Object obj = beanUtilDao.getEntityByClassAndId(clazz, id);
			if (obj == null)
				continue;
			list.add((T) obj);
		}
		return list;
	}

	/**
	 * 通过id集合 获取实体对象 暂时通过遍历一个一个得获取
	 * 
	 * @param ids
	 * @param clazz
	 * @return
	 */
	public <T> List<T> findObjectListByIds(Object ids, Class<?> clazz) {
		List<Serializable> idsArr = LogHelper.convertObjectToListIds(ids);
		return findObjectListByIds(idsArr, clazz);
	}

	/**
	 * 通过指定id集合及表达式向日志对象中添加详细信息 表达式会先找entityExpression,
	 * 如果为空则取log里的operationDetails属性即注释上的operationDetails
	 * 
	 * @param idsObj
	 *            id集合
	 * @param entityExpression
	 *            处理单条记录的表达式 obj代表当前对象
	 * @param log
	 *            日志对象
	 * @param clazz
	 *            对象class
	 */
	public void processEntityListWithExpression(Object idsObj,
			String entityExpression, OperationLog log, Class<?> clazz) {
		List<Serializable> ids = LogHelper.convertObjectToListIds(idsObj);
		if (ids.size() == 0) {
			return;
		}
		List<Object> entitys = findObjectListByIds(ids, clazz);
		LogHelper.processEntityListWithExpression(entitys, entityExpression,
				log);
	}

	/**
	 * 将集合以英文逗号分隔
	 * 
	 * @param names
	 * @return
	 */
	public String joinNames(Collection<String> names) {
		return StringUtils.join(names, ",");
	}

	/**
	 * 是否是新建(业务对象), 可以理解为是否为真
	 * 
	 * @param flag
	 *            通常为业务对象id 以下情况返回真:flag为true, flag为null或空, flag为数字且不大于0
	 * @return
	 */
	public Boolean isNew(Object flag) {
		boolean isNew = false;
		if (ObjectUtils.equals(flag, true)) {
			isNew = true;
		} else if (flag == null || StringHelper.isEmpty(flag.toString())) {
			isNew = true;
		} else if (flag instanceof Number) {
			isNew = ((Number) flag).longValue() <= 0;
		}
		return isNew;
	}

	/**
	 * 日期转换器 将日期转换成yyyy-MM-dd格式
	 */
	public class DateToYMDConverter implements LogConverter {
		public String convert(Object obj) {
			if (obj != null && obj instanceof java.util.Date) {
				return GenericsUtils.getDateStrBySqlDate((java.util.Date) obj);
			}
			return "";
		}
	}

	public class CreateOrEditConverter implements LogConverter {
		public String convert(Object obj) {
			return isNew(obj) ? "新增" : "编辑";
		}
	}

	public class SaveOrUpdateConverter implements LogConverter {
		public String convert(Object obj) {
			return isNew(obj) ? "保存" : "更新";
		}
	}

	/**
	 * bool转换器 返回是或否 参数为 1, "1", true, "true", "TRUE" 返回是
	 */
	public class BooleanTypeConverter implements LogConverter {
		public String convert(Object obj) {
			return obj != null
					&& (ObjectUtils.equals(obj.toString(), "1") || ObjectUtils
							.equals(obj.toString().toLowerCase(), "true")) ? "是"
					: "否";
		}
	}

	public void setBeanUtilDao(BeanUtilDao beanUtilDao) {
		this.beanUtilDao = beanUtilDao;
	}
}
